From 5c27a0dd2bd2a1ea15e583b4447f6160d7079814 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Mon, 3 Apr 2023 10:39:25 -0300 Subject: [PATCH] vulkan: Support fractional scaling Basically what GL does, but without any debug or feature flag to gatekeep it, since the Vulkan backend itself is experimental already. Ceil surface sizes, and floor coordinates, to the fractional scale value. --- gdk/gdkvulkancontext.c | 19 +++++++++++-------- gsk/vulkan/gskvulkanrender.c | 16 ++++++++-------- gsk/vulkan/gskvulkanrenderer.c | 20 ++++++++++---------- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c index 3f669bfc4d..f1f41ce6c9 100644 --- a/gdk/gdkvulkancontext.c +++ b/gdk/gdkvulkancontext.c @@ -26,6 +26,7 @@ #include "gdkdisplayprivate.h" #include +#include /** * GdkVulkanContext: @@ -339,8 +340,10 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context, */ if (capabilities.currentExtent.width == -1 || capabilities.currentExtent.height == -1) { - capabilities.currentExtent.width = MAX (1, gdk_surface_get_width (surface) * gdk_surface_get_scale_factor (surface)); - capabilities.currentExtent.height = MAX (1, gdk_surface_get_height (surface) * gdk_surface_get_scale_factor (surface)); + double scale = gdk_surface_get_scale (surface); + + capabilities.currentExtent.width = MAX (1, (int) ceil (gdk_surface_get_width (surface) * scale)); + capabilities.currentExtent.height = MAX (1, (int) ceil (gdk_surface_get_height (surface) * scale)); } res = GDK_VK_CHECK (vkCreateSwapchainKHR, device, @@ -475,10 +478,10 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context, VkPresentRegionsKHR *regionsptr = VK_NULL_HANDLE; VkPresentRegionsKHR regions; VkRectLayerKHR *rectangles; + double scale; int n_regions; - int scale; - scale = gdk_surface_get_scale_factor (surface); + scale = gdk_surface_get_scale (surface); n_regions = cairo_region_num_rectangles (painted); rectangles = g_alloca (sizeof (VkRectLayerKHR) * n_regions); @@ -490,10 +493,10 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context, rectangles[i] = (VkRectLayerKHR) { .layer = 0, - .offset.x = r.x * scale, - .offset.y = r.y * scale, - .extent.width = r.width * scale, - .extent.height = r.height * scale, + .offset.x = (int) floor (r.x * scale), + .offset.y = (int) floor (r.y * scale), + .extent.width = (int) ceil (r.width * scale), + .extent.height = (int) ceil (r.height * scale), }; } diff --git a/gsk/vulkan/gskvulkanrender.c b/gsk/vulkan/gskvulkanrender.c index b0d4f1f10a..586678c2e4 100644 --- a/gsk/vulkan/gskvulkanrender.c +++ b/gsk/vulkan/gskvulkanrender.c @@ -31,7 +31,7 @@ struct _GskVulkanRender GskRenderer *renderer; GdkVulkanContext *vulkan; - int scale_factor; + double scale; graphene_rect_t viewport; cairo_region_t *clip; @@ -75,14 +75,14 @@ gsk_vulkan_render_setup (GskVulkanRender *self, if (rect) { self->viewport = *rect; - self->scale_factor = 1; + self->scale = 1.0; } else { - self->scale_factor = gdk_surface_get_scale_factor (surface); + self->scale = gdk_surface_get_scale (surface); self->viewport = GRAPHENE_RECT_INIT (0, 0, - gdk_surface_get_width (surface) * self->scale_factor, - gdk_surface_get_height (surface) * self->scale_factor); + (int) ceil (gdk_surface_get_width (surface) * self->scale), + (int) ceil (gdk_surface_get_height (surface) * self->scale)); } if (clip) { @@ -340,12 +340,12 @@ gsk_vulkan_render_add_node (GskVulkanRender *self, GskVulkanRenderPass *pass; graphene_matrix_t mv; - graphene_matrix_init_scale (&mv, self->scale_factor, self->scale_factor, 1.0); + graphene_matrix_init_scale (&mv, self->scale, self->scale, 1.0); pass = gsk_vulkan_render_pass_new (self->vulkan, self->target, - self->scale_factor, - self->scale_factor, + self->scale, + self->scale, &mv, &self->viewport, self->clip, diff --git a/gsk/vulkan/gskvulkanrenderer.c b/gsk/vulkan/gskvulkanrenderer.c index 217cdab717..71ec47b543 100644 --- a/gsk/vulkan/gskvulkanrenderer.c +++ b/gsk/vulkan/gskvulkanrenderer.c @@ -79,11 +79,11 @@ get_render_region (GskVulkanRenderer *self) GdkRectangle whole_surface; GdkRectangle extents; GdkSurface *surface; - int scale; + double scale; render_region = NULL; surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self->vulkan)); - scale = gdk_surface_get_scale_factor (surface); + scale = gdk_surface_get_scale (surface); whole_surface.x = 0; whole_surface.y = 0; @@ -97,10 +97,10 @@ get_render_region (GskVulkanRenderer *self) cairo_rectangle_int_t rect; cairo_region_get_rectangle (damage, i, &rect); cairo_region_union_rectangle (scaled_damage, &(cairo_rectangle_int_t) { - .x = rect.x * scale, - .y = rect.y * scale, - .width = rect.width * scale, - .height = rect.height * scale, + .x = (int) floor (rect.x * scale), + .y = (int) floor (rect.y * scale), + .width = (int) ceil ((rect.x + rect.width) * scale) - floor (rect.x * scale), + .height = (int) ceil ((rect.y + rect.height) * scale) - floor (rect.y * scale), }); } @@ -138,7 +138,7 @@ gsk_vulkan_renderer_update_images_cb (GdkVulkanContext *context, GskVulkanRenderer *self) { GdkSurface *window; - int scale_factor; + double scale; gsize width, height; guint i; @@ -148,9 +148,9 @@ gsk_vulkan_renderer_update_images_cb (GdkVulkanContext *context, self->targets = g_new (GskVulkanImage *, self->n_targets); window = gsk_renderer_get_surface (GSK_RENDERER (self)); - scale_factor = gdk_surface_get_scale_factor (window); - width = gdk_surface_get_width (window) * scale_factor; - height = gdk_surface_get_height (window) * scale_factor; + scale = gdk_surface_get_scale (window); + width = (int) ceil (gdk_surface_get_width (window) * scale); + height = (int) ceil (gdk_surface_get_height (window) * scale); for (i = 0; i < self->n_targets; i++) { -- 2.30.2